﻿using System.Web;
using WikiMaml.Renderers;
using WikiPlex;
using Xunit;
using Xunit.Extensions;

namespace WikiMaml.Facts.Renderers
{
    public class LinkRendererFacts
    {
        public class CanExpand
        {
            [Theory]
            [InlineData(ScopeName.LinkNoText)]
            [InlineData(ScopeName.LinkWithText)]
            [InlineData(ScopeName.LinkAsMailto)]
            public void Should_be_able_to_resolve_scope_name(string scopeName)
            {
                var renderer = new LinkRenderer();

                bool result = renderer.CanExpand(scopeName);

                Assert.True(result);
            }
        }

        public class Expand
        {
            [Fact]
            public void Should_render_the_link_with_no_text_scope_correctly()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand(ScopeName.LinkNoText, "http://localhost", x => x, x => x);

                Assert.Equal("<externalLink><linkText>http://localhost</linkText><linkUri>http://localhost</linkUri></externalLink>", result);
            }

            [Fact]
            public void Should_render_the_link_with_text_scope_correctly()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand(ScopeName.LinkWithText, "Local|http://localhost", x => x, x => x);

                Assert.Equal("<externalLink><linkText>Local</linkText><linkUri>http://localhost</linkUri></externalLink>", result);
            }

            [Fact]
            public void Should_render_the_link_with_text_scope_and_correctly_encoding_the_text()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand(ScopeName.LinkWithText, "&Local|http://localhost", HttpUtility.HtmlEncode, x => x);

                Assert.Equal("<externalLink><linkText>&amp;Local</linkText><linkUri>http://localhost</linkUri></externalLink>", result);
            }

            [Fact]
            public void Should_render_the_link_as_mailto_scope_correctly()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand(ScopeName.LinkAsMailto, "someone@local.com", x => x, x => x);

                Assert.Equal("<externalLink><linkText>someone@local.com</linkText><linkUri>mailto:someone@local.com</linkUri></externalLink>", result);
            }

            [Fact]
            public void Should_render_an_unresolved_macro_if_input_has_more_than_two_parts()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand(ScopeName.LinkWithText, "a|b|c", x => x, x => x);

                Assert.Equal("<markup><span style=\"color:red;font-weight:bold;\">Cannot resolve link macro, invalid number of parameters.</span></markup>", result);
            }

            [Fact]
            public void Should_render_a_correct_link_if_not_prefixed_with_http_and_no_friendly_text()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand(ScopeName.LinkNoText, "www.microsoft.com", x => x, x => x);

                Assert.Equal("<externalLink><linkText>www.microsoft.com</linkText><linkUri>http://www.microsoft.com</linkUri></externalLink>", result);
            }

            [Fact]
            public void Should_render_a_correct_link_if_not_prefixed_with_http_and_with_friendly_text()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand(ScopeName.LinkWithText, "Test|www.microsoft.com", x => x, x => x);

                Assert.Equal("<externalLink><linkText>Test</linkText><linkUri>http://www.microsoft.com</linkUri></externalLink>", result);
            }

            [Fact]
            public void Should_render_a_correct_mailto_link_if_prefixed_with_mailto_and_with_friendly_text()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand(ScopeName.LinkWithText, "Test|mailto:test@user.com", x => x, x => x);

                Assert.Equal("<externalLink><linkText>Test</linkText><linkUri>mailto:test@user.com</linkUri></externalLink>", result);
            }

            [Fact]
            public void Should_trim_url_when_link_has_no_text()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand(ScopeName.LinkNoText, " www.microsoft.com", x => x, x => x);

                Assert.Equal("<externalLink><linkText>www.microsoft.com</linkText><linkUri>http://www.microsoft.com</linkUri></externalLink>", result);
            }

            [Fact]
            public void Should_trim_mailto_correctly()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand(ScopeName.LinkAsMailto, " test@test.com ", x => x, x => x);

                Assert.Equal("<externalLink><linkText>test@test.com</linkText><linkUri>mailto:test@test.com</linkUri></externalLink>", result);
            }

            [Fact]
            public void Should_return_content_for_invalid_scope_name()
            {
                var renderer = new LinkRenderer();

                string result = renderer.Expand("foo", "in", x => x, x => x);

                Assert.Equal("in", result);
            }
        }
    }

}
